<template>
  <div class="super-map-wrap">
    <div style="width: 100%; height: 100%" id="map-container" ref="mapRef" />
    <!-- 工具箱 -->
    <div class="map-tools">
      <el-dropdown v-if="showTools">
        <el-button icon="el-icon-s-tools">工具箱</el-button>
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item>
            <i class="el-icon-refresh"></i>
            <span>复位</span>
          </el-dropdown-item>
          <el-dropdown-item>
            <i class="el-icon-wind-power"></i>
            <span>距离</span>
          </el-dropdown-item>
          <el-dropdown-item>
            <i class="el-icon-location"></i>
            <span>拾取</span>
          </el-dropdown-item>
          <el-dropdown-item>
            <i class="el-icon-delete"></i>
            <span>清除</span>
          </el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
      <el-popover placement="bottom-end" width="300" trigger="click">
        <el-button slot="reference" icon="el-icon-coin">图层控制</el-button>
        <LayerFilter
          v-if="mapInitialized"
          :checkedKeys="checkedKeys"
          @change="layerChange"
          @loaded="handleLoaded"
        />
      </el-popover>
    </div>
    <div class="map-operate"></div>
    <div id="mapType-wrapper"></div>
    <div id="left-panel"></div>
  </div>
</template>

<script>
import { Vector as VectorSource, WMTS, ImageArcGISRest } from "ol/source";
import { Image as ImageLayer, Tile as TileLayer } from "ol/layer";
import VectorLayer from "ol/layer/Vector";
import WMTSTileGrid from "ol/tilegrid/WMTS";
import { getTopLeft } from "ol/extent";
import { get as getProjection } from "ol/proj";
import "ol/ol.css";
import LayerFilter from "./layerFilter.vue";
import { fetchLayerId } from "@/utils";
import cntyPointData from "@/data/cntyPoint";
import riverLabelData from "@/data/riverLabel";
import cityPng from "@/assets/images/city.png";
import shenghuiPng from "@/assets/images/shenghui.png";
import { Feature, Map, View, Collection } from "ol";
import { Point } from "ol/geom";
import { Fill, Stroke, Style, Icon, Text } from "ol/style";
import { OverviewMap, defaults as defaultControls, Zoom } from "ol/control";

export default {
  name: "OpenlayersMap",
  components: { LayerFilter },
  props: {
    center: {
      type: Array,
      required: true,
      validator(value) {
        return (
          value.length === 2 &&
          value.every((coord) => typeof coord === "number")
        );
      },
    },
    zoom: {
      type: Number,
      required: true,
      validator(value) {
        return value >= 0 && value <= 21;
      },
    },
    mapKey: {
      type: String,
      required: true,
    },
    baseUrl: {
      type: String,
      required: true,
    },
    apiKey: {
      type: String,
      required: true,
    },
    showTools: {
      type: Boolean,
      default: true,
    },
    showOverviewMap: {
      type: Boolean,
      default: false,
    },
    zoomControlPosition: {
      type: String,
      default: "topLeft",
    },
  },
  data() {
    return {
      map: null,
      toolbarLayers: {},
      checkedKeys: ["river1", "river2", "lake", "res1", "rlmd_l"],
      tdtLayer: null,
      currentImageLayers: {},
      changshaBoundaryLayer: null,
      mapInitialized: false,
    };
  },
  mounted() {
    this.initMap()
      .then(() => {
        this.loadChangshaLayer();
        this.setCityLabel();
        this.setRiverLabel();
      })
      .then(() => {
        this.mapInitialized = true;
        this.$emit("map-ready", this.map, this.tdtLayer);
      })
      .catch((error) => {
        console.error(
          "Error during map initialization or layer loading:",
          error
        );
      });
  },
  methods: {
    getZoomControlClass(position) {
      const positions = {
        topLeft: "zoom-top-left",
        topRight: "zoom-top-right",
        bottomLeft: "zoom-bottom-left",
        bottomRight: "zoom-bottom-right",
      };
      return positions[position] || "zoom-top-left";
    },
    initMap() {
      return new Promise((resolve, reject) => {
        try {
          const tdtLayer = new TileLayer({
            source: new WMTS({
              url: `http://t1.tianditu.gov.cn/img_c/wmts?tk=${this.mapKey}`,
              layer: "img",
              matrixSet: "c",
              format: "tiles",
              projection: "EPSG:4326",
              tileGrid: new WMTSTileGrid({
                origin: getTopLeft(getProjection("EPSG:4326").getExtent()),
                resolutions: Array(21)
                  .fill(0)
                  .map((_, z) => 1.40625 / Math.pow(2, z)),
                matrixIds: Array.from({ length: 21 }, (_, z) => z.toString()),
              }),
              style: "default",
              wrapX: true,
            }),
          });
          this.tdtLayer = tdtLayer;
          // 定义控件位置的样式
          const zoomControlClass = this.getZoomControlClass(
            this.zoomControlPosition
          );

          let overviewMapControl = null;
          if (this.showOverviewMap) {
            overviewMapControl = new OverviewMap({
              layers: [tdtLayer],
              collapsed: false,
              collapseLabel: "\u00BB",
              label: "\u00AB",
              view: new View({
                projection: "EPSG:4326",
                center: this.center,
                zoom: 6,
              }),
              className: "ol-overviewmap ol-custom-overviewmap",
            });
          }

          this.map = new Map({
            target: this.$refs.mapRef,
            view: new View({
              center: this.center,
              zoom: this.zoom,
              projection: "EPSG:4326",
            }),
            layers: [tdtLayer],
            controls: this.showOverviewMap
              ? defaultControls({ zoom: false }).extend([
                  overviewMapControl,
                  new Zoom({
                    className: zoomControlClass,
                  }),
                ])
              : defaultControls({ zoom: false }).extend([
                  new Zoom({
                    className: zoomControlClass,
                  }),
                ]),
          });

          resolve();
        } catch (error) {
          reject(error);
        }
      });
    },
    loadChangshaLayer() {
      const url =
        "https://172.24.7.214:80/cim/1548461356/geoscene/rest/services/cim/sl_xzqh/MapServer";

      const imageLayer = new ImageLayer({
        source: new ImageArcGISRest({
          ratio: 1, // 确保图片显示比例
          params: {
            layers: "show:0,1,2,3,4,5,6", // 小写参数
            format: "PNG32",
            transparent: true,
            key: "d58b17638488401192fb1ea7929ea795",
          },
          url: url,
        }),
      });

      this.map.addLayer(imageLayer);
    },
    setCityLabel() {
      const siteData = cntyPointData.features;
      const sitePointFeatures = new Collection();
      siteData.forEach((feature) => {
        const coordinate = feature.geometry.coordinates;
        const sitePointFeature = new Feature(new Point(coordinate));
        const siteStyle = new Style({
          image: new Icon({
            src: cityPng,
            scale: 1,
          }),
          text: new Text({
            text: `${feature.properties.NAME}`, // 文本内容
            font: "16px Arial", // 字体样式
            fill: new Fill({ color: "white" }), // 文本颜色
            stroke: new Stroke({ width: 1, color: "black" }), // 文本描边
            offsetX: 0, // 文本横向偏移量
            offsetY: -15, // 文本纵向偏移量
          }),
        });

        const centerStyle = new Style({
          image: new Icon({
            src: shenghuiPng,
            scale: 0.8,
          }),
          text: new Text({
            text: `${feature.properties.NAME}`, // 文本内容
            font: "14px Arial", // 字体样式
            fill: new Fill({ color: "white" }), // 文本颜色
            stroke: new Stroke({ width: 1, color: "black" }), // 文本描边
            offsetX: 0, // 文本横向偏移量
            offsetY: -15, // 文本纵向偏移量
          }),
        });

        // 中心位置
        if (feature.properties.ID === "430100") {
          sitePointFeature.setStyle(centerStyle);
        } else {
          sitePointFeature.setStyle(siteStyle);
        }
        sitePointFeatures.push(sitePointFeature);
      });
      const sitePointSource = new VectorSource({
        features: sitePointFeatures,
      });
      const sitePointLayer = new VectorLayer({
        source: sitePointSource,
      });

      sitePointLayer.setZIndex(this.map.getLayers().getArray().length);
      this.map.addLayer(sitePointLayer);
    },
    setRiverLabel() {
      const riverData = riverLabelData.features;
      const riverPointFeatures = new Collection();
      riverData.forEach((feature) => {
        const coordinate = feature.geometry.coordinates;
        const riverPointFeature = new Feature(new Point(coordinate));
        // 普通样式样式
        const riverStyle = new Style({
          text: new Text({
            text: `${feature.properties.NAME}`, // 文本内容
            font: "16px Arial", // 字体样式
            fill: new Fill({ color: "white" }), // 文本颜色
            stroke: new Stroke({ width: 6, color: "black" }), // 文本描边
            offsetX: 0, // 文本横向偏移量
            offsetY: -15, // 文本纵向偏移量
          }),
        });
        riverPointFeature.setStyle(riverStyle);
        riverPointFeatures.push(riverPointFeature);
      });
      const riverPointSource = new VectorSource({
        features: riverPointFeatures,
      });
      const riverPointLayer = new VectorLayer({
        source: riverPointSource,
      });
      // 图层置顶
      riverPointLayer.setZIndex(this.map.getLayers().getArray().length);
      this.map.addLayer(riverPointLayer);
    },
    async layerChange(checkedNodes) {
      this.checkedKeys = checkedNodes.map((node) => node.layers[0]);

      if (!this.map || !this.map.getView()) {
        console.error("Map has not been initialized");
        return;
      }

      const selectedLayerNames = new Set(this.checkedKeys);

      // 移除未选中的图层
      Object.keys(this.currentImageLayers).forEach((layerName) => {
        if (!selectedLayerNames.has(layerName)) {
          this.map.removeLayer(this.currentImageLayers[layerName]);
          delete this.currentImageLayers[layerName];
        }
      });

      // 添加新选中的图层
      for (const layerName of selectedLayerNames) {
        if (layerName && !this.currentImageLayers[layerName]) {
          try {
            // 获取图层ID
            const layerId = await fetchLayerId(
              this.baseUrl,
              this.apiKey,
              layerName
            );
            if (!layerId) {
              console.error(`Layer ID not found for layer name: ${layerName}`);
              continue;
            }

            const imageLayer = new ImageLayer({
              source: new ImageArcGISRest({
                url: this.baseUrl,
                params: {
                  LAYERS: `show:${layerId}`, // 使用图层ID进行查询
                  FORMAT: "PNG32",
                  TRANSPARENT: true,
                  key: this.apiKey,
                },
              }),
              name: layerName, // 使用图层名作为唯一标识
            });

            console.log("选中的图层", imageLayer);
            this.map.addLayer(imageLayer);
            this.currentImageLayers[layerName] = imageLayer;
          } catch (error) {
            console.error(`Error loading layer ${layerName}:`, error);
          }
        }
      }
    },
    handleLoaded(leafNodeMap, leafIdMap) {
      this.nodeLayerNameMap = leafNodeMap;
      this.checkedLayerMap = leafIdMap;
    },
  },
  beforeDestroy() {
    if (this.map) {
      this.map.setTarget(null);
      this.map = null;
    }
  },
};
</script>

<style>
.super-map-wrap {
  position: relative;
  width: 100%;
  height: 100%;
}
.map-tools {
  position: absolute;
  top: 14px;
  right: 14px;
  font-size: 14px;
  line-height: 14px;
  color: #606266;
  z-index: 10;
  display: flex;
}
.ol-custom-overviewmap {
  position: absolute;
  bottom: 10px;
  right: 10px !important;
  width: 105px;
  height: 105px;
}
.ol-overviewmap {
  left: auto;
  right: 10px !important;
  border: 2px wheat solid;
}
.ol-overviewmap-box {
  border: 1px solid red;
}
/* Zoom 控件位置的样式 */
.zoom-top-left {
  position: absolute;
  top: 10px;
  left: 10px;
}

.zoom-top-right {
  position: absolute;
  top: 10px;
  right: 10px;
}

.zoom-bottom-left {
  position: absolute;
  bottom: 10px;
  left: 10px;
}

.zoom-bottom-right {
  position: absolute;
  bottom: 10px;
  right: 10px;
}
</style>
